package com.sigmazero13.bgjeeves.model;

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import org.xml.sax.Attributes;


import android.sax.Element;
import android.sax.EndElementListener;
import android.sax.EndTextElementListener;
import android.sax.RootElement;
import android.sax.StartElementListener;
import android.util.Xml;

public class GameListParser {
	// XML tags
	static final String ITEMS = "items";
	static final String ITEM = "item";
	static final String NAME = "name";
	static final String STATS = "stats";
	static final String RATING = "rating";
	
	// XML attributes
	static final String OBJECT_ID = "objectid";
	static final String MIN_PLAYERS = "minplayers";
	static final String MAX_PLAYERS = "maxplayers";
	static final String PLAYING_TIME = "playingtime";
	static final String RATING_VALUE = "value";
	
	final URL listUrl;
	
	public GameListParser(String listUrl) {
		try {
			this.listUrl = new URL(listUrl);
		} catch (MalformedURLException e) {
			throw new RuntimeException(e);
		}
	}
	
	protected InputStream getInputStream() {
		try {
			return listUrl.openConnection().getInputStream();
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}
	
	public List<GameInfo> parse() {
		final GameInfo currentGame = new GameInfo();
		RootElement root = new RootElement(ITEMS);
		final List<GameInfo> games = new ArrayList<GameInfo>();
		Element item = root.getChild(ITEM);
		item.setStartElementListener(new StartElementListener() {
			@Override
			public void start(Attributes attributes) {
				try {
					currentGame.setGameId(Integer.parseInt(attributes.getValue(OBJECT_ID)));
				} catch (NumberFormatException e) {
					currentGame.setGameId(0);
				}
			}
		});
		item.setEndElementListener(new EndElementListener() {
			public void end() {
				games.add(currentGame.copy());
			}
		});
		item.getChild(NAME).setEndTextElementListener(new EndTextElementListener() {
			@Override
			public void end(String body) {
				currentGame.setName(body);
			}
		});
		item.getChild(STATS).setStartElementListener(new StartElementListener() {
			@Override
			public void start(Attributes attributes) {
				try {
					currentGame.setMinPlayers(Integer.parseInt(attributes.getValue(MIN_PLAYERS)));
				} catch (NumberFormatException e) {
					currentGame.setMinPlayers(1);
				}
				
				try {
					currentGame.setMaxPlayers(Integer.parseInt(attributes.getValue(MAX_PLAYERS)));
				} catch (NumberFormatException e) {
					currentGame.setMaxPlayers(6);
				}
				
				try {
					currentGame.setBggLength(Integer.parseInt(attributes.getValue(PLAYING_TIME)));
				} catch (NumberFormatException e) {
					currentGame.setBggLength(60);
				}
			}
		});
		item.getChild(STATS).getChild(RATING).setStartElementListener(new StartElementListener() {
			@Override
			public void start(Attributes attributes) {
				try {
					currentGame.setBggRating(Double.parseDouble(attributes.getValue(RATING_VALUE)));
				} catch (NumberFormatException e) {
					currentGame.setBggRating(GameInfo.DEFAULT_RATING);
				}
			}
		});
		
		try {
			Xml.parse(this.getInputStream(), Xml.Encoding.UTF_8, root.getContentHandler());
		} catch (Exception e) {
			return new ArrayList<GameInfo>();
		}
		
		return games;
	}
}
